import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw'
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { Http, RequestOptions, ResponseContentType, RequestMethod } from '@angular/http';
import { appConfig } from '../config/app.config'
import { ServerConfig } from '../config/server'

@Injectable()
export class NetService {

  constructor(private http: Http) { }

  /**
   * 根据服务配置生成通讯地地址
   * @param options
   */
  private generateRequestUrl(options: ServerConfig): string {
    return `${appConfig.url.server}/${options.controller}/${options.action}`
  }

  /**
   * 根据服务配置返回Search参数
   * @param options 
   */
  private generateRequestSearch(options): object {
    if ([RequestMethod.Get].includes(options.service.method)) {
      return options.params
    } else {
      return null
    }
  }

  /**
   * 根据服务配置返回Body参数
   * @param options 
   */
  private generateRequestBody(options): object {
    if ([RequestMethod.Post].includes(options.service.method)) {
      return options.params
    } else {
      return null
    }
  }

  /**
   * 发送网络通讯请求
   * @param options
   */
  send(options: any) {
    let requestUrl: string = this.generateRequestUrl(options.service)
    let requestOptions: RequestOptions = new RequestOptions({
      method: options.service.method,
      search: this.generateRequestSearch(options),
      body: this.generateRequestBody(options),
      responseType: ResponseContentType.Json
    })

    // 生车通讯观察对象
    var observable = Observable.create((observer) => {
      this.http.request(requestUrl, requestOptions)
        .map(response => response.json())
        .catch(response => {
          try {
            let data = response.json()
            return Observable.throw(data)
          } catch (ex) {
            return Observable.throw("网络通讯异常")
          }
        })
        .subscribe((data) => {
          if (data.errno !== 0) {
            observer.error(data)
          } else {
            observer.next(data)
          }
        })
    });

    return observable
  }
}
